#include "commerrno.h"
#include "CActCfg.h"
#include "../mainctrl.h"
#include "commmsg.h"
#include "MsgGM.pb.h"
#include "MsgComm.pb.h"

/************************************************************************/
/*                          CActCfgData                                 */
/************************************************************************/
bool CActCfgData::IsValidSegTime()
{
    for (int i = 0; i < _astSegTime.Size(); ++i)
    {
        if (_astSegTime[i]._iStart < 0 || _astSegTime[i]._iStop <= 0 ||
            _astSegTime[i]._iStop <= _astSegTime[i]._iStart)
        {
            CT_ERROR(("segment time error(start=%d stop=%d)",
                       _astSegTime[i]._iStart,_astSegTime[i]._iStop));
            return false;
        }
        if (i - 1 >= 0 && _astSegTime[i]._iStart <= _astSegTime[i - 1]._iStop)
        {
            CT_ERROR(("segment time error(next start=%d less than last stop=%d)",
                       _astSegTime[i]._iStart,_astSegTime[i - 1]._iStop));
            return false;
        }				
    }

    return true;
}

//后期需要作为唯一活动开关
void CActCfgData::SetStat(char chNewStat, int iBeginTime, int iEndTime)
{
    char chOldStat = _chStat;

    CT_TRACE(("活动(%d)由状态(%d) --> 状态(%d). (%d:自然关闭, %d:自然开启, " \
              "%d:强制关闭, %d:强制开启) BeginTime(%d) EndTime(%d)",
               _shResID,_chStat,chNewStat, ACT_OBJ_STAT_AUTO_CLOSE,
               ACT_OBJ_STAT_AUTO_OPEN, ACT_OBJ_STAT_FORCE_CLOSE,
               ACT_OBJ_STAT_FORCE_OPEN, iBeginTime, iEndTime));

    if (chOldStat == chNewStat)
    {
        return;
    }

    _chStat = chNewStat;
    _iBeginTime = iBeginTime;
    _iEndTime = iEndTime;    

    CMainCtrl::m_pstMain->m_stActMgr.AddNotifyAct(_shResID);
}

void CActCfgData::RefreshAct()
{
    //活动管理实际上是时间的管理
    //1.判断起始和截止日期 配置表默认不填则为0 判断优先级最高
    //2.判断星期 配置表默认不填则为0xFF
    //3.判断是否全天开启
    //4.判断时间段
    //5.是否当前需要更新每日计数器
    //6.是否需要提示活动开启

    //1.判断起始和截止日期 配置表默认不填则为0 判断优先级最高
    if ((_iStopTime > 0 && CMainCtrl::m_pstMain->m_iNow >= _iStopTime) ||
        (_iStartTime > 0 && CMainCtrl::m_pstMain->m_iNow < _iStartTime))
    {
        if (!IsAutoClose() && !IsForceClose())
        {
            return SetStat(ACT_OBJ_STAT_AUTO_CLOSE, _iStartTime, _iStopTime);
        }

        return;
    }

    int iBeginTime = GetBeginTime();
    int iEndTime = GetEndTime();

    int iDayTime = (CMainCtrl::m_pstMain->m_stTm.tm_sec +
                    CMainCtrl::m_pstMain->m_stTm.tm_min * 60 +
                    CMainCtrl::m_pstMain->m_stTm.tm_hour * 3600);
    int iDayZeroTime = CMainCtrl::m_pstMain->m_iDayZeroTime;

    //5.是否当前需要更新每日计数器  --使活动接受截止日期的控制故放在1的判断之后
    //_iUpdateTime=0是为了兼容0点也可以(应该)更新
    if (_iUpdateTime >= 0
        && iDayTime >= _iUpdateTime && GetLastUpdate() < iDayZeroTime)
    {
        CMainCtrl::m_pstMain->m_stActMgr.AddUpdateTime(_iUpdateTime);
        SetLastUpdate(iDayZeroTime);
    }

//用了四个值实际上为了限制在三次以内(左闭右开区间)
#define ACT_TIP_INTERVAL_0 0
#define ACT_TIP_INTERVAL_1 60
#define ACT_TIP_INTERVAL_2 120
#define ACT_TIP_INTERVAL_3 180

    int iSegStart = 0;
    int iTimeTemp = 0;

    bool bCanOpen = false;
    if (IsWeekOpenDay(CMainCtrl::m_pstMain->m_stTm.tm_wday)) //2.判断星期 配置表默认不填则为0xFF
    {
        if (IsAllDayOpen()) //3.判断是否全天开启
        {
            bCanOpen = true;
            iBeginTime = CMainCtrl::m_pstMain->m_iNow;
            iEndTime = 0;
        }
        else
        {
            //6.是否需要提示活动开启  --使活动接受截止日期的控制故放在1的判断之后
            if (_iTipID > 0)
            {
                for (int i = 0; i < _astSegTime.Size(); ++i) //4.判断时间段
                {
                    iSegStart = _astSegTime[i]._iStart;
                    iTimeTemp = iDayZeroTime + _astSegTime[i]._iStart;

                    if (iDayTime >= iSegStart - ACT_TIP_INTERVAL_3 &&
                        _iLastTip < iTimeTemp - ACT_TIP_INTERVAL_2)
                    {
                        CMainCtrl::m_pstMain->m_stActMgr.AddNotifyTip(_iTipID);
                        _iLastTip = iTimeTemp - ACT_TIP_INTERVAL_2;
                    }
                    else if (iDayTime >= iSegStart - ACT_TIP_INTERVAL_2 &&
                             _iLastTip < iTimeTemp - ACT_TIP_INTERVAL_1)
                    {
                        CMainCtrl::m_pstMain->m_stActMgr.AddNotifyTip(_iTipID);
                        _iLastTip = iTimeTemp - ACT_TIP_INTERVAL_1;
                    }
                    else if (iDayTime >= iSegStart - ACT_TIP_INTERVAL_1 &&
                             _iLastTip < iTimeTemp - ACT_TIP_INTERVAL_0)
                    {
                        CMainCtrl::m_pstMain->m_stActMgr.AddNotifyTip(_iTipID);
                        _iLastTip = iTimeTemp - ACT_TIP_INTERVAL_0;
                    }
                }
            }

            for (int i = 0; i < _astSegTime.Size(); ++i) //4.判断时间段
            {
                if (iDayTime >= _astSegTime[i]._iStart &&
                    iDayTime < _astSegTime[i]._iStop)
                {
                    bCanOpen = true;
                    iBeginTime = _astSegTime[i]._iStart + iDayZeroTime;
                    iEndTime = _astSegTime[i]._iStop + iDayZeroTime;
                    break;
                }
            }
        }
    }

    if (bCanOpen)
    {
        //此判断条件适用:强制关闭(或者说提前关闭)活动并要求必须达到下次自然开启时间段才开启
        //例如世界BOSS活动[击杀BOSS活动强制关闭 不能改变上一个时间段的关闭时刻(GetEndTime)]
        if (IsForceClose() && iBeginTime > 0 && iBeginTime > GetEndTime())
        {
            return SetStat(ACT_OBJ_STAT_AUTO_OPEN, iBeginTime, iEndTime);
        }

        if (!IsAutoOpen() && !IsForceOpen() && !IsForceClose())
        {
            return SetStat(ACT_OBJ_STAT_AUTO_OPEN, iBeginTime, iEndTime);
        }
    }
    else
    {
        //此判断条件适用:强制开启了活动并且设置了活动的关闭时间
        //例如星门召唤活动[家族官员可以任意时刻开启 一段时间(30分)后关闭]
        //例如GM强制开启活动
        if (IsForceOpen() && GetEndTime() > 0 &&
                CMainCtrl::m_pstMain->m_iNow >= GetEndTime())
        {
            return SetStat(ACT_OBJ_STAT_AUTO_CLOSE, iBeginTime, iEndTime);
        }

        if (!IsAutoClose() && !IsForceClose() && !IsForceOpen())
        {
            return SetStat(ACT_OBJ_STAT_AUTO_CLOSE, iBeginTime, iEndTime);
        }
    }
}

//公共类活动的获取
void CActCfgData::GetActInfo(MsgActInfo& stActInfo)
{
    //ACT_OBJ_FRONT_STAT_BEFORE_OPEN      = 1,    //早于(还未开始)
    //ACT_OBJ_FRONT_STAT_CLOSE_ALREADY    = 2,    //晚于(已经结束)
    //ACT_OBJ_FRONT_STAT_RUNNING          = 3,    //满足(正在进行)
    //
    //如果是早于 前端要求如果可以取到下次开启时间就返回给前端

    stActInfo.set_act_id(_shResID);

    //正在进行
    if (IsActOpen())
    {
        stActInfo.set_act_status(ACT_OBJ_FRONT_STAT_RUNNING);
        return;
    }

    //配置了开启日期但是日期未到
    if (_iStartTime > 0 && CMainCtrl::m_pstMain->m_iNow < _iStartTime)
    {
        stActInfo.set_act_status(ACT_OBJ_FRONT_STAT_BEFORE_OPEN);
        stActInfo.set_start_time(_iStartTime);
        return;
    }

    //配置了关闭日期但是日期已过
    if (_iStopTime > 0 && CMainCtrl::m_pstMain->m_iNow >= _iStopTime)
    {
        stActInfo.set_act_status(ACT_OBJ_FRONT_STAT_CLOSE_ALREADY);
        return;
    }

    //当日不是一周内开启的那天
    if (!IsWeekOpenDay(CMainCtrl::m_pstMain->m_stTm.tm_wday))
    {
        stActInfo.set_act_status(ACT_OBJ_FRONT_STAT_BEFORE_OPEN);
        return;
    }

    int iDayTime = (CMainCtrl::m_pstMain->m_stTm.tm_sec +
                    CMainCtrl::m_pstMain->m_stTm.tm_min * 60 +
                    CMainCtrl::m_pstMain->m_stTm.tm_hour * 3600);
    int iDayZeroTime = CMainCtrl::m_pstMain->m_iDayZeroTime;

    //判断所处的时间段
    for (int i = 0; i < _astSegTime.Size(); ++i)
    {
        if (iDayTime < _astSegTime[i]._iStart)
        {
            stActInfo.set_act_status(ACT_OBJ_FRONT_STAT_BEFORE_OPEN);
            stActInfo.set_start_time(_astSegTime[i]._iStart + iDayZeroTime);
            return;
        }
        else if (iDayTime >= _astSegTime[i]._iStop)
        {
            if (i + 1 == _astSegTime.Size())
            {
                stActInfo.set_act_status(ACT_OBJ_FRONT_STAT_CLOSE_ALREADY);
                return;
            }
        }
    }

    if (_astSegTime.Size() <= 0)
    {
        //完全没有配置日期、星期、时间段则默认未开启
        stActInfo.set_act_status(ACT_OBJ_FRONT_STAT_BEFORE_OPEN);
    }
    else
    {
        //极有可能只有一个时间但是提前结束了
        //完全没有配置日期、星期、时间段则默认未开启
        stActInfo.set_act_status(ACT_OBJ_FRONT_STAT_CLOSE_ALREADY);
    }
}

//特殊活动的获取
void CActCfgData::GetActInfo(MsgActInfo& stActInfo, int iStatus)
{
    stActInfo.set_act_id(_shResID);
    stActInfo.set_act_status(iStatus);

    int iDayTime = (CMainCtrl::m_pstMain->m_stTm.tm_sec +
                    CMainCtrl::m_pstMain->m_stTm.tm_min * 60 +
                    CMainCtrl::m_pstMain->m_stTm.tm_hour * 3600);
    int iDayZeroTime = CMainCtrl::m_pstMain->m_iDayZeroTime;

    if (ACT_ID_CLAN_BATTLE == _shResID)
    {
        for (int i = 0; i < _astSegTime.Size(); ++i)
        {
            if (iDayTime < _astSegTime[i]._iStart)
            {
                stActInfo.set_start_time(_astSegTime[i]._iStart + iDayZeroTime);
                break;
            }
            if (i - 1 >= 0 && i - 1 < _astSegTime.Size())
            {
                stActInfo.set_start_time(
                    _astSegTime[i - 1]._iStart + iDayZeroTime);
            }
        }
    }
}

int CActCfgData::GMDealAct(MsgReqGMPlayer& stReq, MsgAnsGMPlayer& stAns,
        bool bActOpen, CTSizeString<MAX_BATTLE_NAME_BUFF>& szNameStr)
{
    switch (stReq.sub_type())
    {
    case ID_GM_PLAYER_SUB_GET_ACT_STATUS:
        {
            szNameStr.Cat("\n状态:%d ",_chStat);
            szNameStr.Cat("ID:%d ",_shResID);
            szNameStr.Cat("类型:%d ",_chType);
            szNameStr.Cat("场景:%d ",_shSceneID);
            szNameStr.Cat("星期:%d ",_ucOpenDays);
            szNameStr.Cat("全天:%d ",_bAllDayOpen);
            szNameStr.Cat("更新:%d ",_iUpdateTime);
            szNameStr.Cat("上次:%d ",_iLastUpdate);
            szNameStr.Cat("提示:%d ",_iTipID);
            szNameStr.Cat("开始:%d ",_iBeginTime);
            szNameStr.Cat("结束:%d ",_iEndTime);
            szNameStr.Cat("起始:%d ",_iStartTime);
            szNameStr.Cat("截止:%d ",_iStopTime);
            
            szNameStr.Cat("段:%d",_astSegTime.Size());
            for (int i = 0; i < _astSegTime.Size(); ++i)
            {
                szNameStr.Cat(" [%d:%d]",_astSegTime[i]._iStart,
                              _astSegTime[i]._iStop);
            }
        }
        break;
    case ID_GM_PLAYER_SUB_SET_ACT_STATUS://设置活动运行时状态(1表示强制开启 0表示强制关闭)
        {
            int iBeginTime = GetBeginTime();
            int iEndTime = GetEndTime();
            
            int iDayTime = (CMainCtrl::m_pstMain->m_stTm.tm_sec +
                            CMainCtrl::m_pstMain->m_stTm.tm_min * 60 +
                            CMainCtrl::m_pstMain->m_stTm.tm_hour * 3600);
            int iDayZeroTime = CMainCtrl::m_pstMain->m_iDayZeroTime;
            
            CMainCtrl::m_pstMain->m_stActMgr.ClearNotifyAndUpdateTime();//先简单清理

            if (bActOpen)
            {
                iBeginTime = CMainCtrl::m_pstMain->m_iNow;

                for (int i = 0; i < _astSegTime.Size(); ++i)
                {
                    if (iDayTime < _astSegTime[i]._iStop)
                    {
                        iEndTime = _astSegTime[i]._iStop + iDayZeroTime;
                        break;
                    }
                }

                if (iEndTime <= iBeginTime)
                {
                    iEndTime = iBeginTime + 60 * 60;
                }

                if (!IsAutoOpen() && !IsForceOpen())
                {
                    SetStat(ACT_OBJ_STAT_FORCE_OPEN, iBeginTime, iEndTime);
                    CMainCtrl::m_pstMain->m_stActMgr.ActStatChange();
                }
            }
            else
            {
                iEndTime = CMainCtrl::m_pstMain->m_iNow;
                if (iBeginTime > iEndTime)
                {
                    iBeginTime = iEndTime;
                }

                if (!IsAutoClose() && !IsForceClose())
                {
                    SetStat(ACT_OBJ_STAT_FORCE_CLOSE, iBeginTime, iEndTime);
                    CMainCtrl::m_pstMain->m_stActMgr.ActStatChange();
                }
            }
        }
        break;
    default:
        return ERROR_MAIN_SUB_CMD;
    }

    return 0;
}

/************************************************************************/
/*                          CActCfg                                     */
/************************************************************************/
int CActCfg::AddConfig(CActCfgData& stCfgData)
{
    if (!stCfgData.IsValidID())
    {
        return ERROR_ACT_ERROR_CFG;
    }
    
    int iIndex = _stActCfgHash.HashFind(stCfgData.GetResID());
    if (iIndex >= 0)
    {
        return ERROR_ACT_REPEAT_RESID;
    }

    iIndex = _stActCfgHash.HashAlloc(stCfgData.GetResID());
    if (iIndex < 0)
    {
        return RET_SYSTEM_FAIL;
    }

    _stActCfgHash[iIndex] = stCfgData;

    return 0;
}

int CActCfg::FindConfig(short shResID)
{
    if (shResID <= 0)
    {
        CT_WARNING(("ResID(%d) invalid!", shResID));
        return -1;//因为返回下标 所以这里必须返回负数
    }

    int iIndex = _stActCfgHash.HashFind(shResID);
    if (iIndex < 0)
    {
        CT_WARNING(("ResID(%d) config empty!", shResID));
        return -1;//因为返回下标 所以这里必须返回负数
    }

    return iIndex;
}

CActCfgData& CActCfg::GetConfig(int iIndex)
{
    return _stActCfgHash[iIndex];
}

void CActCfg::RefreshAct()
{
    if (_stActCfgHash.Size(T_ACT_CFG_HASH::USED_LIST) <= 0)
    {
        return;
    }

    int iIndex = _stActCfgHash.GetHeadIndex();

    while (iIndex >= 0)
    {
        _stActCfgHash[iIndex].RefreshAct();

        iIndex = _stActCfgHash.GetNextIndex(iIndex);
    }
}

int CActCfg::GMDealAct(MsgReqGMPlayer& stReq, MsgAnsGMPlayer& stAns)
{
    CTSizeString<MAX_BATTLE_NAME_BUFF> szNameStr;

    switch (stReq.sub_type())
    {
    case ID_GM_PLAYER_SUB_GET_ACT_STATUS:
        {
            int iDayTime = (CMainCtrl::m_pstMain->m_stTm.tm_sec +
                            CMainCtrl::m_pstMain->m_stTm.tm_min * 60 +
                            CMainCtrl::m_pstMain->m_stTm.tm_hour * 3600);
            int iDayZeroTime = CMainCtrl::m_pstMain->m_iDayZeroTime;

            szNameStr.Cat("当前时间戳:%d 零点时间戳:%d 当天秒值:%d " \
                "系统停机时刻:%d 下次提示时刻:%d\n",
                CMainCtrl::m_pstMain->m_iNow, iDayZeroTime, iDayTime,
                CMainCtrl::m_pstMain->m_stActMgr.GetSysStopTime(),
                CMainCtrl::m_pstMain->m_stActMgr.GetNextNoticeSysStop());

            szNameStr.Cat("活动总数:%d",
                _stActCfgHash.Size(T_ACT_CFG_HASH::USED_LIST));

            int iIndex = _stActCfgHash.GetHeadIndex();
            
            while (iIndex >= 0)
            {
                _stActCfgHash[iIndex].GMDealAct(stReq, stAns, true, szNameStr);

                iIndex = _stActCfgHash.GetNextIndex(iIndex);
            }

            stAns.set_name(szNameStr.Get());
        }
        break;
    case ID_GM_PLAYER_SUB_SET_ACT_STATUS://设置活动运行时状态(1表示强制开启 0表示强制关闭)
        {
            bool bActOpen = false;
            short shActResID = 0;
            int iIndex = 0;

            if (stReq.datas_size() == 1)
            {
                shActResID = (short)stReq.datas(0);
                bActOpen = true;
            }
            else if (stReq.datas_size() >= 2)
            {
                shActResID = (short)stReq.datas(0);
                if (stReq.datas(1) != 0)
                {
                    bActOpen = true;
                }
            }

            iIndex = FindConfig(shActResID);
            if (iIndex >= 0)
            {
                CMainCtrl::m_pstMain->m_stActMgr.ClearNotifyAndUpdateTime();//先简单清理
                CActCfgData& stActCfgData = GetConfig(iIndex);
                stActCfgData.GMDealAct(stReq, stAns, bActOpen, szNameStr);
                CMainCtrl::m_pstMain->m_stActMgr.ActStatChange();
            }
        }
        break;
    default:
        return ERROR_MAIN_SUB_CMD;
    }

    return 0;
}

void CActCfg::GetActList(MsgTips& stTips)
{
    if (_stActCfgHash.Size(T_ACT_CFG_HASH::USED_LIST) <= 0)
    {
        return;
    }

    short shActID = 0;
    int iIndex = _stActCfgHash.GetHeadIndex();

    while (iIndex >= 0)
    {
        shActID = _stActCfgHash[iIndex].GetResID();
        //需要特别定制的活动需要剔除 在CActMgr::GetActList处理
        if (ACT_ID_CLAN_BATTLE == shActID ||
            ACT_ID_MAGIC_DOOR == shActID ||
            ACT_ID_CLAN_DICE == shActID ||
            ACT_ID_CLAN_TREE == shActID ||
            ACT_ID_CLAN_SKILL == shActID ||
            ACT_ID_CLAN_SHOP == shActID ||
            ACT_ID_MAGIC_CONTRIBUTE == shActID ||
            ACT_ID_CLAN_DAIL == shActID ||
            ACT_ID_NEW_SALES == shActID ||
            ACT_ID_ACA_CUP == shActID)
        {
            iIndex = _stActCfgHash.GetNextIndex(iIndex);
            continue;
        }
        
        MsgActInfo* pstActInfo = stTips.add_act();
        if (pstActInfo)
        {
            _stActCfgHash[iIndex].GetActInfo(*pstActInfo);
        }
        else
        {
            CT_ERROR(("tip add act pointer null!"));
        }

        iIndex = _stActCfgHash.GetNextIndex(iIndex);
    }
}

/************************************************************************/
/*                          CActStatusCfgData                           */
/************************************************************************/
int CActStatusCfg::AddConfig(CActStatusCfgData& stCfgData)
{
    if (!stCfgData.IsValidID())
    {
        return ERROR_ACT_ERROR_CFG;
    }
    
    int iIndex = _stActStatusCfgHash.HashFind(stCfgData.GetActID());
    if (iIndex >= 0)
    {
        return ERROR_ACT_STATUS_REPEAT_RESID;
    }

    iIndex = _stActStatusCfgHash.HashAlloc(stCfgData.GetActID());
    if (iIndex < 0)
    {
        return RET_SYSTEM_FAIL;
    }

    _stActStatusCfgHash[iIndex] = stCfgData;

    return 0;
}

int CActStatusCfg::FindConfig(short shActID)
{
    if (shActID <= 0)
    {
        CT_WARNING(("ActID(%d) invalid!", shActID));
        return -1;//因为返回下标 所以这里必须返回负数
    }

    int iIndex = _stActStatusCfgHash.HashFind(shActID);
    if (iIndex < 0)
    {
        CT_WARNING(("ActID(%d) config empty!", shActID));
        return -1;//因为返回下标 所以这里必须返回负数
    }

    return iIndex;
}

CActStatusCfgData& CActStatusCfg::GetConfig(int iIndex)
{
    return _stActStatusCfgHash[iIndex];
}

//////////////////////////////////////////////////////////////////////////
//宝箱争夺战
int CFightForBoxConfig::AddConfig(const pb_cfg_act_pb_cfg_fight_for_box_unit& stConfigUnit)
{
    switch (stConfigUnit.cfg_type())
    {
    case 1:  //宝箱配置
        {
            if (stConfigUnit.box_type() < CFightForBoxConfig::BOX_TYPE_MIN
                || stConfigUnit.box_type() > CFightForBoxConfig::BOX_TYPE_MAX)
            {
                CT_ERROR(("%d", stConfigUnit.box_type()));
                return RET_SYS_ERROR;
            }

            if (_aucBoxTypeTemplate.Size() + stConfigUnit.box_count() > _aucBoxTypeTemplate.GetCount())
            {
                CT_ERROR((""));
                return RET_SYS_ERROR;
            }

            for (int i = 0; i < stConfigUnit.box_count(); ++i)
            {
                _aucBoxTypeTemplate.AddOneItem((unsigned char)stConfigUnit.box_type());
            }
        }
        break;
    case 2:  //NPC配置
        {
            _aiAllNPC.AddOneItem(stConfigUnit.npc_id());
        }
        break;
    case 3:  //奖励兑换
        {
            if (_astExchangeBonus.Size() == _astExchangeBonus.GetCount())
            {
                CT_ERROR((""));
                return RET_SYS_ERROR;
            }

            CFightForBoxBonusConfig _stBonusConfig;
            _stBonusConfig._iID = stConfigUnit.exchange_item_id();
            _stBonusConfig._iNeedPoint = stConfigUnit.need_point();
            _stBonusConfig._uiTips = stConfigUnit.send_mar();

            _stBonusConfig._stDropItemData._ucItemType = stConfigUnit.bonus_type();
            _stBonusConfig._stDropItemData._usItemConfigID = stConfigUnit.bonus_id();
            _stBonusConfig._stDropItemData._iItemCount = stConfigUnit.bonus_count();

            for (int i = 0; i < _astExchangeBonus.Size(); ++i)
            {
                if (_stBonusConfig._iID == _astExchangeBonus[i]._iID)
                {
                    CT_ERROR(("%d", _stBonusConfig._iID));
                    return RET_SYS_ERROR;
                }
            }

            _astExchangeBonus.AddOneItem(_stBonusConfig);
        }
        break;
    case 4:  //排名奖励精力
        {
            if (_astRankBonus.Size() == _astRankBonus.GetCount())
            {
                CT_ERROR((""));
                return RET_SYS_ERROR;
            }

            CFightForBoxRankBonusConfig _stRankBonusConfig;
            _stRankBonusConfig._iRank = stConfigUnit.rank();
            _stRankBonusConfig._iBonusEnergy = stConfigUnit.rank_add_energy();

            if (_stRankBonusConfig._iRank <= 0 || _stRankBonusConfig._iRank > MAX_FIGHT_FOR_BOX_ROLE_COUNT)
            {
                CT_ERROR(("%d", _stRankBonusConfig._iRank));
                return RET_SYS_ERROR;
            }

            for (int i = 0; i < _astRankBonus.Size(); ++i)
            {
                if (_astRankBonus[i]._iRank == _stRankBonusConfig._iRank)
                {
                    CT_ERROR(("%d", _stRankBonusConfig._iRank));
                    return RET_SYS_ERROR;
                }
            }

            _astRankBonus.AddOneItem(_stRankBonusConfig);
        }
        break;
    case 5:  //慧眼购买
        {
            _iCanBuyEyeCount = stConfigUnit.max_can_buy_eye_count();
            _iEyePrice = stConfigUnit.eye_price();

            if (_iCanBuyEyeCount <= 0 || _iEyePrice <= 0)
            {
                CT_ERROR(("%d, %d", _iCanBuyEyeCount, _iEyePrice));
                return RET_SYS_ERROR;
            }
        }
        break;
    case 6:  //1积分可兑换银币数
        {
            _iOnePointToSilver = stConfigUnit.point_to_silver();

            if (_iOnePointToSilver <= 0)
            {
                CT_ERROR(("%d", _iOnePointToSilver));
                return RET_SYS_ERROR;
            }
        }
        break;
    default:
        CT_ERROR(("未知的配置类型, %d", stConfigUnit.cfg_type()));
        return RET_SYS_ERROR;
    }

    return 0;
}

//////////////////////////////////////////////////////////////////////////
//一战到底
int CFightEndConfig::AddLevelConfig(CFightEndCfgData& stCfgData)
{
    int iRet = 0;

    if (!stCfgData.IsValidLevel())
    {
        return ERROR_FIGHT_END_OVER_RESID;
    }
    
    if (_astConfig.Size() >= _astConfig.GetCount())
    {
        return ERROR_FIGHT_END_FULL_CFG;
    }

    //这个排序必须要保证
    for (int i = 0; i < _astConfig.Size(); ++i)
    {
        if (stCfgData.GetLevel() <= _astConfig[i].GetLevel())
        {
            return ERROR_FIGHT_END_ERROR_CFG;
        }
    }

    iRet = _astConfig.AddOneItem(stCfgData);
    if (iRet < 0)
    {
        CT_ERROR(("fight end add level config(%d) error(%d)",
                  stCfgData.GetLevel(), iRet));
        return RET_SYSTEM_FAIL;
    }

    return 0;
}

int CFightEndConfig::FindLevelConfig(int iLevel)
{
    if (iLevel <= 0)
    {
        CT_ERROR(("Level id(%d) invalid!", iLevel));
        return -1;//因为返回下标 所以这里必须返回负数
    }

    //左闭右开区间的搜索
    for (int i = _astConfig.Size() - 1; i >= 0; --i)
    {
        if (iLevel >= _astConfig[i].GetLevel())
        {
            return i;
        }
    }

    return -1;
}

CFightEndCfgData& CFightEndConfig::GetLevelConfig(int iIndex)
{
    return _astConfig[iIndex];
}

int CNewZoneSalesConfig::AddItemConfig(CNewZoneSalesItem& stCfgData)
{
    if (_astConfig.Size() >= NEWZONE_SALES_ITEM_CNT)
    {
        return ERROR_NEWSALES_FULL_CFG;
    }

    _astConfig.AddOneItem(stCfgData);
    
    return RET_OK;
}


int CNewZoneSalesConfig::GetItemConfig (int iPos, CNewZoneSalesItem & stItem)
{
    if (iPos < 1 || iPos > NEWZONE_SALES_ITEM_CNT)
    {
        return ERROR_NEWSALES_PARA_ERR;
    }
    
    stItem = _astConfig[iPos - 1];
    
    return RET_OK;
}
